<template>
	<div class="component-upload-file">
		<el-upload
			:action="action"
			:headers="headers"
			:multiple="limit === 1 ? false : true"
			:data="data"
			drag
			:on-change="onChange"
			:on-remove="onRemoveUpload"
			:on-success="onUploadSuccess"
			:on-error="onErrorUpload"
			:on-exceed="onExceedUpload"
			:before-upload="onBeforeUpload"
			:file-list="fileList"
			list-type="text"
			:auto-upload="autoUpload"
			:disabled="disabled"
			:limit="limit"
			ref="imageUploadRef"
		>
			<el-icon size="32">
				<ele-UploadFilled />
			</el-icon>
			<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
			<template #tip v-if="isShowTip">
				<el-alert
					:title="`上传文件支持 ${fileType.join(' / ')} 格式，单个文件大小不超过 ${fileSize}MB，且文件数量不超过 ${limit} 个`"
					type="info"
					show-icon
					:closable="false"
					style="line-height: 16px; margin-top: 10px"
				/>
			</template>
		</el-upload>
	</div>
</template>

<script setup lang="ts" name="FileUpload">
import { reactive, ref } from 'vue';
import { ElMessage, ElLoading } from 'element-plus';
import { Session } from '/@/utils/storage';

// 定义父组件传过来的值
const props = defineProps({
	action: {
		type: String,
		default: '',
	},
	headers: {
		type: Object,
		default: () => {
			return {
				sign: 'admin',
				token: Session.get('token'),
			};
		},
	},
	data: {
		type: Object,
		default: () => {
			return {};
		},
	},
	fileList: {
		type: Array,
		default: () => [],
	},
	// 数量限制
	limit: {
		type: Number,
		default: 1,
	},
	// 类型, 例如['png', 'jpg', 'jpeg']
	fileType: {
		type: Array,
		default: () => ['xlsx', 'xls'],
	},
	// 大小限制(MB)
	fileSize: {
		type: Number,
		default: 1,
	},
	// modelValue: {
	// 	type: String,
	// 	default: '',
	// },
	disabled: {
		type: Boolean,
		default: false,
	},
	autoUpload: {
		type: Boolean,
		default: true,
	},
	// 是否显示提示
	isShowTip: {
		type: Boolean,
		default: true,
	},
});
const state = reactive({
	fileList: [] as any,
});

// 定义子组件向父组件传值/事件
const emit = defineEmits(['update:modelValue', 'fileUpload']);

const uploadLoading = ref();
const imageUploadRef = ref();

/********** 点击事件(on开头) **********/
// 选择的文件
const onChange = (file: any) => {
	state.fileList.push(file);
};
// 删除文件
const onRemoveUpload = (file: any) => {
	const findex = props.fileList.map((f: any) => f.name).indexOf(file.name);
	findex > -1 && emit('fileUpload', { data: [], msg: '', findex }, file);
};
// 上传成功回调
const onUploadSuccess = (res: any, file: any) => {
	emit('fileUpload', res, file);
	uploadLoading.value.close();
};
// 上传失败
const onErrorUpload = () => {
	ElMessage.warning('上传文件失败，请重试');
	uploadLoading.value.close();
};
// 上传前校验
const onBeforeUpload = (file: any) => {
	let isFormat = false;
	let fileExtension = '';
	if (file.name.lastIndexOf('.') > -1) {
		fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1);
	}
	isFormat = props.fileType.some((type: any) => {
		if (file.type.indexOf(type) > -1) return true;
		if (fileExtension && fileExtension.indexOf(type) > -1) return true;
		return false;
	});

	if (!isFormat) {
		ElMessage.warning(`文件格式不正确, 请上传${props.fileType.join('/')}格式!`);
		return false;
	}
	if (props.fileSize) {
		const isSize = file.size / 1024 / 1024 < props.fileSize;
		if (!isSize) {
			ElMessage.warning(`上传文件大小不能超过 ${props.fileSize} MB!`);
			return false;
		}
	}
	uploadLoading.value = ElLoading.service({
		lock: true,
		text: '正在上传文件，请稍候...',
		spinner: 'el-icon-loading',
		background: 'rgba(0, 0, 0, 0.7)',
	});
};
const onExceedUpload = (files: any, uploadFiles: any) => {
	ElMessage.warning(`当前限制选择 ${props.limit} 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + uploadFiles.length} 个文件`);
};
// 初始化
const initialize = () => {
	state.fileList = [];
};
// 上传文件
const submit = () => {
	if (!state.fileList.length) {
		ElMessage.warning('上传文件不能为空');
		return;
	}
	imageUploadRef.value.clearFiles();
	imageUploadRef.value.handleStart(state.fileList[0].raw)
	imageUploadRef.value.submit();
};

/********** 方法向父组件暴露 **********/
defineExpose({ initialize, submit });
</script>
